home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
castools.zip
/
ADDTOGRO.C
< prev
next >
Wrap
Text File
|
1990-02-15
|
6KB
|
232 lines
/*
ADDTOGRO.C Function PbAddToGroup: Adds a person entry to a group entry.
INPUT: Phonebook structure, and the record id's of the person and group
entries.
OUTPUT: If successful, adds the person to the group's members list, and the
group to the person's members list. If the new member changes the
group's HardwareType, that field is changed.
*/
#include <stdio.h>
#include <malloc.h>
#include <phonebk.h>
int pascal PbAddToGroup(PB *pb, int GroupID, int MemberID)
{
int retval = FAIL; /* default, if anything goes wrong */
PBE *group = NULL,
*member = NULL;
LONGWORD group_offset,
member_offset;
int new_free_bytes;
int buffed_rids;
int i,
writ, /* for return value of fwrite() */
filenum;
int temperrno = 0; /* for saving aside Pberrno */
Pberrno = 0; /* Initially, always reset */
/* First, check params */
if (pb == NULL) {
Pberrno = INVALIDPARAMETER;
return(NULL);
}
if ((GroupID < 0) ||
(GroupID > 999)) {
Pberrno = INVALIDPARAMETER;
return(NULL);
}
if ((MemberID < 0) ||
(MemberID > 999)) {
Pberrno = INVALIDPARAMETER;
return(NULL);
}
/* First, fetch the entries */
if (!(group = PbGetEntry(pb, NULL, NULL, GroupID))) {
goto getout; /* PbGetEntry sets Pberrno */
}
if (!(member = PbGetEntry(pb, NULL, NULL, MemberID))) {
goto getout;
}
/* A few consistency checks */
if (member->type != PERSONENTRY) {
Pberrno = GROUPCANTBEMEMBER;
goto getout;
}
if (group->type != GROUPENTRY) {
Pberrno = PERSONCANTHAVEMEMBER;
goto getout;
}
/* Check that the group doesn't already have the person as a member */
for (i=0; i<group->members; i++) {
if (group->MemberList[i] == MemberID) {
break;
}
}
if (i != group->members) {
Pberrno = ENTRYALREADYMEMBER;
goto getout;
}
/* Check that operation will not put phonebook's 'unused bytes' over limit */
if (new_free_bytes = (pb->header.FreeBytes +
group->length +
member->length) > MAXUNUSEDBYTES) {
Pberrno = TOOMANYFREEBYTES;
goto getout;
}
/* Update fields of both entries */
group->MemberList = (int *)realloc(group->MemberList,
(group->members + 1) * sizeof(int));
group->MemberList[group->members++] = MemberID;
group->length += sizeof(int);
member->MemberList = (int *)realloc(member->MemberList,
(member->members + 1) * sizeof(int));
member->MemberList[member->members++] = GroupID;
member->length += sizeof(int);
/* Set or change the hardware type of the group as appropriate */
if (group->members == 1) { /* we're adding the first member */
group->HardwareType = member->HardwareType;
}
else if ((group->HardwareType == HASCCC) &&
(member->HardwareType == FAXONLY)) {
group->HardwareType = FAXONLY;
}
/* Find out new offsets for the entries, in case the write is successful */
filenum = fileno(pb->fp);
if ((member_offset = filelength(filenum)) == -1L) {
Pberrno = FILELENGTHERROR;
goto getout;
}
group_offset = member_offset + member->length;
/* Write the person entry to end of the file, quitting if error occurs */
if (fseek(pb->fp, 0L, SEEK_END)) {
Pberrno = FSEEKERROR;
goto getout;
}
/* First, write the fixed part... */
writ = fwrite(member, sizeof(PBEFIXED), 1, pb->fp);
if (writ != 1) {
Pberrno = CANTWRITE;
goto getout;
}
/* ... then each of the optional fields, INCLUDING their NULL terminator... */
for (i=0; i<pb->header.fields; i++) {
writ = fwrite(member->fields[i], strlen(member->fields[i]) + 1, 1, pb->fp);
if (writ != 1) {
Pberrno = CANTWRITE;
goto getout;
}
}
/* ... and finally the membership list */
writ = fwrite(member->MemberList,
sizeof(int),
member->members,
pb->fp);
if (writ != member->members) {
Pberrno = CANTWRITE;
goto getout;
}
/* And write the group, too: first the fixed part, ... */
writ = fwrite(group, sizeof(PBEFIXED), 1, pb->fp);
if (writ != 1) {
Pberrno = CANTWRITE;
goto getout;
}
/* ...then the membership list */
writ = fwrite(group->MemberList,
sizeof(int),
group->members,
pb->fp);
if (writ != group->members) {
Pberrno = CANTWRITE;
goto getout;
}
/* If we got here, can update record ID's offsets and other pb fields*/
/* If the Offset buffer is being used, check there for the id's */
if (pb->OBuffer) {
buffed_rids = pb->OBufferSize/sizeof(LONGWORD);
/* If the id's are in the buffer, update them there */
if ((MemberID >= pb->FirstOBufferRID) &&
(MemberID < pb->FirstOBufferRID + buffed_rids)) {
pb->OBuffer[MemberID - pb->FirstOBufferRID] = member_offset;
}
if ((GroupID >= pb->FirstOBufferRID) &&
(GroupID < pb->FirstOBufferRID + buffed_rids)) {
pb->OBuffer[GroupID - pb->FirstOBufferRID] = group_offset;
}
}
/* And finally do the actual writes to the file */
if (fseek(pb->fp, 160L + MemberID * sizeof(LONGWORD), SEEK_SET)) {
Pberrno = FSEEKERROR;
goto getout;
}
writ = fwrite(&member_offset, sizeof(LONGWORD), 1, pb->fp);
if (writ != 1) {
Pberrno = CANTWRITE;
goto getout;
}
if (fseek(pb->fp, 160L + GroupID * sizeof(LONGWORD), SEEK_SET)) {
Pberrno = FSEEKERROR;
goto getout;
}
writ = fwrite(&group_offset, sizeof(LONGWORD), 1, pb->fp);
if (writ != 1) {
Pberrno = CANTWRITE;
goto getout;
}
/* And now set the FreeBytes phonebook field */
pb->header.FreeBytes = new_free_bytes;
if (fseek(pb->fp, 6L, SEEK_SET)) {
Pberrno = FSEEKERROR;
goto getout;
}
writ = fwrite(&pb->header.FreeBytes, sizeof(int), 1, pb->fp);
if (writ != 1) {
Pberrno = CANTWRITE;
goto getout;
}
/* If we got all the way to here, all went well! */
retval = SUCCESS;
getout:
if (Pberrno) {
temperrno = Pberrno;
}
if (group) {
PbFreePBE(pb, group);
}
if (member) {
PbFreePBE(pb, member);
}
if (temperrno) {
Pberrno = temperrno;
}
return(retval);
}